using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using ZoneFiveSoftware.Common.Data;
using ZoneFiveSoftware.Common.Data.Fitness;
using ZoneFiveSoftware.Common.Visuals;
using FilteredStatistics.Common;
using FilteredStatistics.View;
using FilteredStatistics.Controller;

namespace FilteredStatistics.Data
{
    class AllActiveOrRestLapsNamedZone : INamedZone
    {
        public AllActiveOrRestLapsNamedZone(IActivity activity, bool restLapsDesired)
        {
            m_ActivityCallbackHelper = new ActivityDataChangedHelper(activity);
            m_ActivityCallbackHelper.PropertyChanged += new PropertyChangedEventHandler(OnActivityDataChanged);

            Activity = activity;
            m_RestLapsDesired = restLapsDesired;

            m_ValidTimesDirty = true;
        }

#region INamedZone Members

        public String Name
        {
            get
            {
                if (m_RestLapsDesired)
                {
                    return PluginView.GetLocalizedString("AllRestLapsText");
                }
                else
                {
                    return PluginView.GetLocalizedString("AllActiveLapsText");
                }
            }
        }

        public IValueRangeSeries<DateTime> ValidTimes
        {
            get
            {
                RefreshValidTimes();

                return m_ValidRanges;
            }
        }

        public event PropertyChangedEventHandler ValidTimesChanged;

#endregion

        private void OnActivityDataChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "LapInfo.Rest" ||
                e.PropertyName == "Activity.Duration")
            {
                m_ValidTimesDirty = true;
                TriggerValidTimesChanged();
            }
        }

        protected void TriggerValidTimesChanged()
        {
            if (ValidTimesChanged != null)
            {
                ValidTimesChanged(this, new PropertyChangedEventArgs("ValidTimes"));
            }
        }

        private void RefreshValidTimes()
        {
            if (m_ValidTimesDirty)
            {
                m_ValidTimesDirty = false;

                m_ValidRanges.Clear();

                if (Activity != null)
                {
                    ActivityInfo activityInfoCache = ActivityInfoCache.Instance.GetInfo(Activity);

                    foreach (LapDetailInfo lapDetails in activityInfoCache.RecordedLapDetailInfo)
                    {
                        // We changed from invalid to valid lap or vice-versa
                        if (lapDetails.Rest == m_RestLapsDesired)
                        {
                            // Quitting an active lap
                            m_ValidRanges.Add(new ValueRange<DateTime>(lapDetails.StartTime, lapDetails.EndTime));
                        }
                    }
                }
            }
        }

        public IActivity Activity
        {
            get { return m_Activity; }
            set
            {
                if (Activity != value)
                {
                    m_Activity = value;
                    m_ActivityCallbackHelper.Activity = m_Activity;

                    m_ValidTimesDirty = true;
                    TriggerValidTimesChanged();
                }
            }
        }

        private IActivity m_Activity = null;
        private ActivityDataChangedHelper m_ActivityCallbackHelper = null;
        private bool m_RestLapsDesired = false;
        private IValueRangeSeries<DateTime> m_ValidRanges = new ValueRangeSeries<DateTime>();
        private bool m_ValidTimesDirty = false;
    }
}
